[Linux] [TPM driver] Resume frontend after checkpointing
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 2 Mar 2007 16:03:21 +0000 (16:03 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 2 Mar 2007 16:03:21 +0000 (16:03 +0000)
This patch implements TPM frontend driver resume after checkpointing a
domain. I also now let the front-end wait for the response from the
TPM until the response is there. A response must come due to the
strict request/response nature of the protocol, but the time until the
responses arrives depends on the type of operation that is executed by
the vTPM. Resending a request is not possible with this type of device.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c

index 88ad1c1f8086b3e1b13baec6c90167dc6bb4f350..0c1caa8d9f5ffb2e2d469a77b1d760c020d4ec3b 100644 (file)
@@ -421,7 +421,7 @@ static int tpmfront_suspend(struct xenbus_device *dev)
        mutex_lock(&suspend_lock);
        tp->is_suspended = 1;
 
-       for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 300; ctr++) {
+       for (ctr = 0; atomic_read(&tp->tx_busy); ctr++) {
                if ((ctr % 10) == 0)
                        printk("TPM-FE [INFO]: Waiting for outstanding "
                               "request.\n");
@@ -430,19 +430,24 @@ static int tpmfront_suspend(struct xenbus_device *dev)
                 */
                interruptible_sleep_on_timeout(&tp->wait_q, 100);
        }
-       xenbus_switch_state(dev, XenbusStateClosing);
 
-       if (atomic_read(&tp->tx_busy)) {
-               /*
-                * A temporary work-around.
-                */
-               printk("TPM-FE [WARNING]: Resetting busy flag.");
-               atomic_set(&tp->tx_busy, 0);
-       }
+       return 0;
+}
 
+static int __tpmfront_suspend_cancel(struct tpm_private *tp)
+{
+       tp->is_suspended = 0;
+       /* unlock, so apps can send again */
+       mutex_unlock(&suspend_lock);
        return 0;
 }
 
+static int tpmfront_suspend_cancel(struct xenbus_device *dev)
+{
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
+       return __tpmfront_suspend_cancel(tp);
+}
+
 static int tpmfront_resume(struct xenbus_device *dev)
 {
        struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
@@ -484,6 +489,7 @@ static struct xenbus_driver tpmfront = {
        .resume = tpmfront_resume,
        .otherend_changed = backend_changed,
        .suspend = tpmfront_suspend,
+       .suspend_cancel = tpmfront_suspend_cancel,
 };
 
 static void __init init_tpm_xenbus(void)
@@ -689,9 +695,7 @@ static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
         * This also removes the suspend state.
         */
        if (is_connected == 1 && tp->is_suspended == 1) {
-               tp->is_suspended = 0;
-               /* unlock, so apps can resume sending */
-               mutex_unlock(&suspend_lock);
+               __tpmfront_suspend_cancel(tp);
        }
 
        if (is_connected != tp->is_connected) {